const { EventEmitter } = require('events')

/**
 * 交易策略基类
 *
 * 提供所有策略的基础功能和标准接口
 * 包含性能统计、错误处理、配置管理等功能
 */
class BaseStrategy extends EventEmitter {
  /**
   * 构造函数
   * @param {string} name 策略名称
   * @param {Object} config 策略配置
   */
  constructor (name, config = {}) {
    super()

    this.name = name
    this.config = {
      enabled: true,
      priority: 50,
      parameters: {},
      riskSettings: {
        maxPosition: 0.3, // 最大仓位比例
        stopLoss: 0.05, // 止损比例
        takeProfit: 0.15, // 止盈比例
        maxDrawdown: 0.1 // 最大回撤
      },
      performance: {
        minConfidence: 0.3, // 最小置信度
        executionTimeout: 5000, // 执行超时时间(ms)
        cooldownPeriod: 60000 // 冷却期(ms)
      },
      ...config
    }

    // 性能统计
    this.stats = {
      executionCount: 0,
      successCount: 0,
      errorCount: 0,
      totalLatency: 0,
      lastExecution: null,
      lastSuccess: null,
      lastError: null,
      signalHistory: []
    }

    // 运行时状态
    this.isExecuting = false
    this.lastCooldown = 0
  }

  /**
   * 检查策略执行条件
   * 子类必须实现此方法
   *
   * @param {Object} marketData 市场数据
   * @param {Object} analysisData 分析数据
   * @returns {boolean} 是否满足执行条件
   */
  checkConditions (marketData, analysisData) {
    throw new Error(`Strategy ${this.name} must implement checkConditions method`)
  }

  /**
   * 生成交易信号
   * 子类必须实现此方法
   *
   * @param {Object} marketData 市场数据
   * @param {Object} analysisData 分析数据
   * @returns {Object|null} 交易信号
   */
  generateSignal (marketData, analysisData) {
    throw new Error(`Strategy ${this.name} must implement generateSignal method`)
  }

  /**
   * 执行策略
   * 主要执行流程控制方法
   *
   * @param {Object} marketData 市场数据
   * @param {Object} analysisData 分析数据
   * @returns {Object|null} 交易信号
   */
  async execute (marketData, analysisData) {
    const startTime = Date.now()

    try {
      // 检查冷却期
      if (this.isInCooldown()) {
        return null
      }

      // 检查是否正在执行
      if (this.isExecuting) {
        return null
      }

      this.isExecuting = true
      this.stats.executionCount++

      // 检查策略是否启用
      if (!this.config.enabled) {
        this.emit('debug', `Strategy ${this.name} is disabled`)
        return null
      }

      // 验证输入数据
      this.validateInputData(marketData, analysisData)

      // 检查执行条件
      if (!this.checkConditions(marketData, analysisData)) {
        this.emit('debug', `Strategy ${this.name} conditions not met`)
        return null
      }

      // 生成信号
      const signal = await this.generateSignalWithTimeout(marketData, analysisData)

      if (signal) {
        this.stats.successCount++
        this.stats.lastSuccess = Date.now()

        // 丰富信号数据
        const enrichedSignal = this.enrichSignal(signal, marketData, analysisData)

        // 记录信号历史
        this.recordSignal(enrichedSignal)

        // 更新冷却期
        this.lastCooldown = Date.now()

        this.emit('signalGenerated', enrichedSignal)
        return enrichedSignal
      }

      return null
    } catch (error) {
      this.stats.errorCount++
      this.stats.lastError = {
        timestamp: Date.now(),
        message: error.message,
        stack: error.stack
      }

      this.emit('error', {
        strategy: this.name,
        error: error.message,
        marketData: this.sanitizeDataForLog(marketData),
        analysisData: this.sanitizeDataForLog(analysisData)
      })

      // 根据错误类型决定是否抛出
      if (this.isCriticalError(error)) {
        throw error
      }

      return null
    } finally {
      const executionTime = Date.now() - startTime
      this.stats.totalLatency += executionTime
      this.stats.lastExecution = Date.now()
      this.isExecuting = false

      this.emit('executed', {
        strategy: this.name,
        executionTime,
        success: !this.stats.lastError || this.stats.lastError.timestamp < startTime
      })
    }
  }

  /**
   * 带超时的信号生成
   * @private
   */
  async generateSignalWithTimeout (marketData, analysisData) {
    return new Promise((resolve, reject) => {
      const timeout = setTimeout(() => {
        reject(new Error(`Strategy ${this.name} execution timeout`))
      }, this.config.performance.executionTimeout)

      try {
        const signal = this.generateSignal(marketData, analysisData)
        clearTimeout(timeout)
        resolve(signal)
      } catch (error) {
        clearTimeout(timeout)
        reject(error)
      }
    })
  }

  /**
   * 丰富信号数据
   * @private
   */
  enrichSignal (signal, marketData, analysisData) {
    const executionTime = Date.now() - (this.stats.lastExecution || Date.now())

    return {
      ...signal,
      metadata: {
        strategy: this.name,
        timestamp: Date.now(),
        executionTime,
        confidence: signal.confidence || this.calculateConfidence(analysisData),
        qualityScore: this.calculateQualityScore(signal, marketData, analysisData),
        riskLevel: this.assessSignalRisk(signal, marketData),
        expectedDuration: this.estimateSignalDuration(signal, analysisData),
        ...(signal.metadata || {})
      }
    }
  }

  /**
   * 计算信号置信度
   * 子类可以重写此方法提供更精确的计算
   *
   * @param {Object} analysisData 分析数据
   * @returns {number} 置信度 0-1
   */
  calculateConfidence (analysisData) {
    // 基础置信度计算逻辑
    let confidence = 0.5

    // 可以基于分析数据进行调整
    // 子类应该重写此方法提供具体的计算逻辑

    return Math.min(Math.max(confidence, 0), 1)
  }

  /**
   * 计算信号质量得分
   * @private
   */
  calculateQualityScore (signal, marketData, analysisData) {
    let score = 0.5

    // 置信度权重
    score += (signal.confidence || 0.5) * 0.4

    // 市场条件权重
    if (this.isMarketConditionsFavorable(marketData)) {
      score += 0.2
    }

    // 多时间框架确认权重
    if (this.hasMultiTimeframeConfirmation(analysisData)) {
      score += 0.3
    }

    // 历史成功率权重
    const successRate = this.getSuccessRate()
    score += successRate * 0.1

    return Math.min(Math.max(score, 0), 1)
  }

  /**
   * 评估信号风险
   * @private
   */
  assessSignalRisk (signal, marketData) {
    let riskScore = 0

    // 市场波动率风险
    const volatility = marketData.volatility || 0.03
    if (volatility > 0.05) riskScore += 30

    // 信号置信度风险
    const confidence = signal.confidence || 0.5
    if (confidence < 0.6) riskScore += 25

    // 市场环境风险
    if (marketData.isMarketChaos) riskScore += 25

    // 流动性风险
    if ((marketData.liquidity || 1.0) < 0.8) riskScore += 20

    if (riskScore >= 70) return 'EXTREME'
    if (riskScore >= 50) return 'HIGH'
    if (riskScore >= 30) return 'MEDIUM'
    return 'LOW'
  }

  /**
   * 估算信号持续时间
   * @private
   */
  estimateSignalDuration (signal, analysisData) {
    // 基于信号类型和市场条件估算持续时间（分钟）
    const baseMinutes = {
      'BUY': 120,
      'SELL': 120,
      'PING_DUO': 60,
      'PING_KONG': 60
    }

    let duration = baseMinutes[signal.type] || 120

    // 根据置信度调整
    const confidence = signal.confidence || 0.5
    duration *= (0.5 + confidence)

    // 根据市场条件调整
    if (analysisData.marketFlagInfo?.ifMarket15mAllGood || analysisData.marketFlagInfo?.ifMarket15mAllBad) {
      duration *= 1.5 // 明确趋势时信号持续时间更长
    }

    return Math.round(duration)
  }

  /**
   * 计算仓位倍数
   *
   * @param {number} confidence 信号置信度
   * @param {string} riskLevel 风险等级
   * @returns {number} 仓位倍数
   */
  calculatePositionMultiplier (confidence, riskLevel) {
    const riskMultipliers = {
      'LOW': 1.0,
      'MEDIUM': 0.8,
      'HIGH': 0.5,
      'EXTREME': 0.2
    }

    const baseMultiplier = riskMultipliers[riskLevel] || 0.5
    const confidenceMultiplier = 0.5 + (confidence * 0.5) // 0.5-1.0范围

    return baseMultiplier * confidenceMultiplier
  }

  /**
   * 验证输入数据
   * @private
   */
  validateInputData (marketData, analysisData) {
    if (!marketData || typeof marketData !== 'object') {
      throw new Error('Invalid marketData: must be an object')
    }

    if (!analysisData || typeof analysisData !== 'object') {
      throw new Error('Invalid analysisData: must be an object')
    }

    // 检查必要的分析数据
    const requiredFields = ['analysisInfo15m', 'analysisInfo1h', 'analysisInfo4h']
    requiredFields.forEach(field => {
      if (!analysisData[field]) {
        throw new Error(`Missing required field: ${field}`)
      }
    })
  }

  /**
   * 检查是否在冷却期
   * @private
   */
  isInCooldown () {
    if (!this.lastCooldown) return false
    return (Date.now() - this.lastCooldown) < this.config.performance.cooldownPeriod
  }

  /**
   * 记录信号历史
   * @private
   */
  recordSignal (signal) {
    this.stats.signalHistory.push({
      timestamp: Date.now(),
      type: signal.type,
      reason: signal.reason,
      confidence: signal.confidence,
      positionRate: signal.positionRate
    })

    // 保持历史记录在合理范围内
    if (this.stats.signalHistory.length > 100) {
      this.stats.signalHistory = this.stats.signalHistory.slice(-50)
    }
  }

  /**
   * 判断是否为关键错误
   * @private
   */
  isCriticalError (error) {
    const criticalPatterns = [
      /timeout/i,
      /network/i,
      /connection/i,
      /database/i
    ]

    return criticalPatterns.some(pattern => pattern.test(error.message))
  }

  /**
   * 清理敏感数据用于日志记录
   * @private
   */
  sanitizeDataForLog (data) {
    // 移除敏感信息，只保留关键字段用于调试
    if (!data) return data

    const sanitized = {}
    const safeFields = ['timestamp', 'type', 'priority', 'confidence']

    safeFields.forEach(field => {
      if (data[field] !== undefined) {
        sanitized[field] = data[field]
      }
    })

    return sanitized
  }

  /**
   * 检查市场条件是否有利
   * @private
   */
  isMarketConditionsFavorable (marketData) {
    // 基础的市场条件检查
    return !marketData.isMarketChaos && (marketData.liquidity || 1.0) >= 0.8
  }

  /**
   * 检查是否有多时间框架确认
   * @private
   */
  hasMultiTimeframeConfirmation (analysisData) {
    // 简单的多时间框架确认检查
    const timeframes = ['analysisInfo15m', 'analysisInfo1h', 'analysisInfo4h']
    let confirmCount = 0

    timeframes.forEach(tf => {
      if (analysisData[tf] && (analysisData[tf].macd > 0 || analysisData[tf].kdjDiff > 0)) {
        confirmCount++
      }
    })

    return confirmCount >= 2
  }

  /**
   * 获取成功率
   */
  getSuccessRate () {
    if (this.stats.executionCount === 0) return 0
    return this.stats.successCount / this.stats.executionCount
  }

  /**
   * 获取策略统计信息
   *
   * @returns {Object} 统计信息
   */
  getStatistics () {
    const avgLatency = this.stats.executionCount > 0
      ? this.stats.totalLatency / this.stats.executionCount
      : 0

    const successRate = this.getSuccessRate()
    const errorRate = this.stats.executionCount > 0
      ? this.stats.errorCount / this.stats.executionCount
      : 0

    return {
      name: this.name,
      enabled: this.config.enabled,
      priority: this.config.priority,
      executionCount: this.stats.executionCount,
      successCount: this.stats.successCount,
      errorCount: this.stats.errorCount,
      successRate: successRate,
      errorRate: errorRate,
      averageLatency: avgLatency,
      lastExecution: this.stats.lastExecution,
      lastSuccess: this.stats.lastSuccess,
      lastError: this.stats.lastError,
      signalCount: this.stats.signalHistory.length,
      isExecuting: this.isExecuting,
      inCooldown: this.isInCooldown()
    }
  }

  /**
   * 重置统计信息
   */
  resetStatistics () {
    this.stats = {
      executionCount: 0,
      successCount: 0,
      errorCount: 0,
      totalLatency: 0,
      lastExecution: null,
      lastSuccess: null,
      lastError: null,
      signalHistory: []
    }

    this.emit('statisticsReset', { strategy: this.name })
  }

  /**
   * 更新配置
   *
   * @param {Object} newConfig 新配置
   */
  updateConfig (newConfig) {
    const oldConfig = { ...this.config }
    this.config = { ...this.config, ...newConfig }

    this.emit('configUpdated', {
      strategy: this.name,
      oldConfig,
      newConfig: this.config
    })
  }

  /**
   * 启用策略
   */
  enable () {
    this.config.enabled = true
    this.emit('enabled', { strategy: this.name })
  }

  /**
   * 禁用策略
   */
  disable () {
    this.config.enabled = false
    this.emit('disabled', { strategy: this.name })
  }

  /**
   * 获取最近的信号历史
   *
   * @param {number} count 获取数量
   * @returns {Array} 信号历史
   */
  getRecentSignals (count = 10) {
    return this.stats.signalHistory.slice(-count)
  }

  /**
   * 清理资源
   */
  destroy () {
    this.removeAllListeners()
    this.stats.signalHistory = []
    this.isExecuting = false
    this.lastCooldown = 0
  }
}

module.exports = BaseStrategy
